﻿using System;
using System.Collections.Generic;
using SCG.General;
using SCG.SolarVengeanceEngine.BrainInfo;

namespace SCG.SolarVengeanceEngine
{
    //Represents a StarSystem
    public class StarSystem : SVMapObject
    {
        //constructor
        public StarSystem(SVGame game)
            : base(game)
        {
            if (Game != null)
                Game.StarSystems.Add(this);
        }

        //remove from the game
        public override void Remove()
        {
            base.Remove();
            if (Game != null)
                Game.StarSystems.Remove(this);
        }

        //StarSystem's name
        public string Name { get; set; }

        //use it as display name
        public override string DisplayName
        {
            get
            {
                return Name;
            }
        }

        //StarSystem value - determines how quickly it generates resources
        public int Value { get; set; }

        //The player owning the StarSystem, or null if unowned
        public Player Owner
        {
            get
            {
                return _owner;
            }
            set
            {
                _owner = value;

                //If there's a bonus StarShip type give it to the owner
                if (Owner != null)
                    if (BonusValue > 0)
                        if (!Owner.ShipTypesAvailable.Contains(BonusShipType))
                        {
                            Owner.ShipTypesAvailable.Add(BonusShipType);
                            Owner.ShipTypesAvailable.Sort();
                        }
            }
        }
        public bool OwnedByCurrentPlayer
        {
            get
            {
                return Owner == Game.CurrentPlayer;
            }
        }

        //Color - based on owner
        public SCGColor Color
        {
            get
            {
                if (!VisibleToCurrentPlayer)
                    return SCGColor.Gray;
                if (Owner == null)
                    return SCGColor.Silver;
                else
                    return Owner.Color;
            }       
        }

        //Is it the capital for a player?
        public bool IsCapital
        {
            get
            {
                if (Owner == null)
                    return false;
                return Owner.Capital == this;
            }
        }

        //The bonus StarShip type (if any)
        public StarShipType BonusShipType { get; set; }

        //Bonus when building the bonus StarShip type (if any)
        public double BonusValue { get; set; }

        //Resources currently at the StarSystem
        public double Resources { get; set; }

        //Number of Scanners
        public int Scanners { get; set; }

        //Number of Shields
        public int Shields { get; set; }

        //Get int value of resources
        public int ResourcesInt
        {
            get
            {
                return (int)Resources;
            }
        }

        //AutoBuilding?
        public bool AutoShields { get; set; }

        public bool AutoScanners { get; set; }

        public bool AutoStarShip { get; set; }

        //What type of ship is autobuilding?
        public StarShipDescriptor AutoStarShipType
        {
            get
            {
                //Set auto ship-type
                if (Owner != null)
                    if (!Owner.ShipTypesAvailable.Contains(_autoShipType.ShipType))
                    {
                        if (Owner.ShipTypesAvailable.Count > 0)
                        {
                            _autoShipType.ShipType = Owner.ShipTypesAvailable[0];
                            StarShip dummy = StarShip.CreateInstance(null, null, _autoShipType.ShipType, 0, 0, null);
                            if (_autoShipType.ShipType.GetFixedEngines() > 0)
                                _autoShipType.Engines = _autoShipType.ShipType.GetFixedEngines();
                            if (_autoShipType.ShipType.GetPrimarySystemName() == "")
                                _autoShipType.Value = 0;
                        }
                    }
                return _autoShipType;
            }
            set
            {
                _autoShipType = value;
            }
        }

        //Was a JumpGate created here?
        public bool JumpGateCreated { get; set; }

        //Zealot influence
        public bool WasInfluencedBy(Player p)
        {
            if (_influenced == null)
                return false;
            return _influenced[p];
        }
        public void Influence(Player p)
        {
            if (_influenced == null)
                _influenced = new Dictionary<Player, bool>();
            _influenced[p] = true;
        }
        public void ClearInfluence()
        {
            _influenced = null;
        }

        //Persistence
        public override string Persist()
        {           
            SVTokenizer tok = new SVTokenizer(Game);
            tok.Tokenize(Name, Value, Owner, BonusShipType, BonusValue, Resources, Scanners, Shields,
                AutoShields, AutoScanners, AutoStarShip, AutoStarShipType, JumpGateCreated);
            return base.Persist() + tok.Result;
        }
        public override SVTokenizer Parse(string s)
        {
            SVTokenizer tok = base.Parse(s);
            Name = tok.TokenString;
            Value = tok.TokenInt;
            Owner = tok.TokenPlayer;
            BonusShipType = tok.TokenStarShipType;
            BonusValue = tok.TokenDouble;
            Resources = tok.TokenDouble;
            Scanners = tok.TokenInt;
            Shields = tok.TokenInt;
            AutoShields = tok.TokenBoolean;
            AutoScanners = tok.TokenBoolean;
            AutoStarShip = tok.TokenBoolean;
            AutoStarShipType = tok.TokenStarShipDescriptor;
            JumpGateCreated = tok.TokenBoolean;
            return tok;
        }

        //For debugging
        public override string ToString()
        {
            return Name;
        }

        //private members
        private Player _owner = null;
        private StarShipDescriptor _autoShipType = new StarShipDescriptor(StarShipType.WarShip, 8, 4, false);
        private StarSystemInfo _info = null;
        private Dictionary<Player, bool> _influenced;

        //Produce resources at the StarSystem
        internal void ProduceResources()
        {
            if (Owner != null)
                Resources += (((double)Value / 40.0d) * Owner.TechMultiple);
        }

        //Get the Brain Info object
        internal StarSystemInfo Info
        {
            get
            {
                if (_info == null)
                    _info = new StarSystemInfo(this);
                return _info;
            }
        }
    }
}
